package org.spdata.tsdb.client;

import java.util.Iterator;
import java.util.LinkedList;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spdata.tsdb.client.Client.State;


public class ClientFactory {
	static Logger logger = LoggerFactory.getLogger(ClientFactory.class);
	private LinkedList<Client> clients = new LinkedList<Client>();;
	private String host;
	private int port;
	private int maxConnections;
	
	
	public int getMaxConnections() {
		return maxConnections;
	}
	public void setMaxConnections(int maxConnections) {
		this.maxConnections = maxConnections;
	}
	public String getHost() {
		return host;
	}
	public void setHost(String host) {
		this.host = host;
	}
	public int getPort() {
		return port;
	}
	public void setPort(int port) {
		this.port = port;
	}
	
	public void removeClient(Client client) {
		this.clients.remove(client);
	}
	
	public  Client getClient(Object caller) throws Exception{
		Client client = null;		
		
		synchronized(clients) {
			Iterator<Client> iter = clients.iterator();			
			while(iter.hasNext()){
				Client one = iter.next();
				if(one.getHolded()!=null) {
					logger.debug(" {} is holded by [{}],current thread is {}" ,one,one.getHolded(),Thread.currentThread().getName());
					continue;
				}
				
				if(one.isClosed()) {
					iter.remove();
					continue;
				}
				if(one.getState().equals(State.idle)) {
					client = one;
					break;
				}
			}

			if(client==null && clients.size()<this.maxConnections) {
				try {
					client = Client.getInstance(host, port);
				}catch(Exception e) {
					logger.error("failed to get a new client!"+e.getMessage());
				}
				if(client!=null) {
					clients.add(client);
					logger.info("get a new client,current client amount is "+clients.size());
				}
			}
			
			if(client==null) {
				//最终无法获得client
				throw new Exception("can not get a idle client!");
			}else{
				client.setHolded(caller);
				logger.debug("hold a tsdb client {} by {}",client,caller);
			}
		}
		
		return client;
	}
	
}
